/*
 * cell_locator.h
 *
 *  Created on: 31.7.2012
 *      Author: stebel
 */

#ifndef CELL_LOCATOR_H_
#define CELL_LOCATOR_H_

#include "mesh.h"

#define TOL_FACE_DISTANCE 1e-6

class CellLocator {
public:
	/**
	 * Constructor.
	 * @param _mesh      Mesh.
	 * @param _surface   Surface id.
	 * @param _res_x Number of boxes in x direction.
	 * @param _res_y Number of boxes in y direction.
	 * @param _res_z Number of boxes in z direction.
	 */
	CellLocator(Mesh *_mesh, int _surface, int _res_x, int _res_y, int _res_z);

	/**
	 * Destructor.
	 */
	virtual ~CellLocator();

	/**
	 * Searches for a cell containing the given point.
	 * @param x X coordinate.
	 * @param y Y coordinate.
	 * @param z Z coordinate.
	 * @param u Barycentric coordinate (returned if cell was found).
	 * @param v Barycentric coordinate (returned if cell was found).
	 */
	int find_cell(double x, double y, double z, double &u, double &v);

	/**
	 * Searches for a cell containing the given point.
	 * @param x X coordinate.
	 * @param y Y coordinate.
	 * @param z Z coordinate.
	 */
	int find_cell(double x, double y, double z) { double u, v; return find_cell(x, y, z, u, v); };

	/**
	 * Returns the id of box containing the given point.
	 * @param x X coordinate.
	 * @param y Y coordinate.
	 * @param z Z coordinate.
	 */
	int box_id_by_point(double x, double y, double z);

	bool point_in_triangle(double x, double y, double z, int e, double &u, double &v);

private:
	/** Pointer to the mesh. */
	Mesh *mesh;

	/**
	 * Id of the surface containing the cells (faces).
	 */
	int surface;

	/** Coordinates of bounding box.
	 * First index stands for the coordinate (x/y/z),
	 * second index for the lower/upper bound.
	 */
	double bounds[3][2];

	/**
	 * Size of small boxes.
	 */
	double sizes[3];

	/**
	 * Number of boxes in each direction.
	 */
	int resolution[3];

	map<int, set<int> > box_faces;
};

#endif /* CELL_LOCATOR_H_ */
